package nio.example.study.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import nio.example.study.client.codec.*;
import nio.example.study.client.codec.dispatcher.ClientIdleCheckHandler;
import nio.example.study.client.codec.dispatcher.OperationResultFuture;
import nio.example.study.client.codec.dispatcher.RequestPendingCenter;
import nio.example.study.client.codec.dispatcher.ResponseDispatcherHandler;
import nio.example.study.common.OperationResult;
import nio.example.study.common.RequestMessage;
import nio.example.study.common.order.OrderOperation;
import nio.example.study.util.IdUtil;

import java.util.concurrent.ExecutionException;

public class ClientV2 {

	public static void main(String[] args) throws ExecutionException, InterruptedException {
		Bootstrap bootstrap = new Bootstrap();
		bootstrap.channel(NioSocketChannel.class);
		bootstrap.group(new NioEventLoopGroup());
		RequestPendingCenter requestPendingCenter = new RequestPendingCenter();

		bootstrap.handler(new ChannelInitializer<NioSocketChannel>() {
			@Override
			protected void initChannel(NioSocketChannel ch) throws Exception {
				ChannelPipeline pipeline = ch.pipeline();

				pipeline.addLast(new OrderFrameDecoder());
				pipeline.addLast(new OrderFrameEncoder());
				pipeline.addLast(new OrderProtocolEncoder());
				pipeline.addLast(new OrderProtocolDecoder());

				pipeline.addLast(new ResponseDispatcherHandler(requestPendingCenter));
				//pipeline.addLast(new OperationToRequestMessageEncoder());
				pipeline.addLast(new LoggingHandler(LogLevel.INFO));
			}
		});
		ChannelFuture channelFuture = bootstrap.connect("127.0.0.1",8090);
		channelFuture.sync();

		// 生成消息
		long streamId = IdUtil.nextId();
		RequestMessage requestMessage = new RequestMessage(streamId,new OrderOperation(1001, "tudou"));

		// 将消息的streamId与future那么会都没活
		OperationResultFuture operationResultFuture = new OperationResultFuture();
		requestPendingCenter.add(requestMessage.getMessageHeader().getStreamId(),operationResultFuture);

		// 写入请求
		channelFuture.channel().writeAndFlush(requestMessage);

		// 获取返回结果
		OperationResult operationResult = operationResultFuture.get();
		System.out.println(operationResult);

		channelFuture.channel().closeFuture().get();
	}
}
